﻿#include "dataoperate.h"

DataOperate::DataOperate(QObject *parent) :
    QObject(parent)
  , m_checkRange(0.3)
  , m_maxRangeY(10)
  , m_saveFileName("")
  , m_isUpFlag(false)
{

}




void DataOperate::getIniConfData()
{
    m_listConfData = PlotChartUtils::GetInstance().getConfData();
}

void DataOperate::getIniConfData(QString path)
{
    m_saveFileName = path;
    m_listConfData = PlotChartUtils::GetInstance().getConfData(path);
}


//void DataOperate::getFileNames()
//{
//    QList<QString> fileNames = PlotChartUtils::GetInstance().
//    m_listConfData = PlotChartUtils::GetInstance().getConfData();
//}


void DataOperate::getCntConfDataValue(QList<ConfData> &listConfData)
{
    qSort(m_listConfData.begin(), m_listConfData.end(), [=](const ConfData &confData1,
          const ConfData &confData2){
        return confData1.index < confData2.index;
    });
    listConfData = m_listConfData;
}

QList<ConfData> DataOperate::getListConfData()
{
    return m_listConfData;
}



QString DataOperate::setUUID(int index, QString name)
{
    return QString("%1_%2").arg(index).arg(name);
}

int DataOperate::getIndexByUUID(QString UUID)
{
    if(UUID.indexOf("_") != -1)
    {
        QStringList strList = UUID.split("_");
        if(!strList.isEmpty())
        {
            return QString(strList.at(0)).toInt();
        }
    }
    return -1;
}

QList<ConfData> DataOperate::initChartData()
{
    getIniConfData();
    return m_listConfData;
}



// UUID格式index_name
bool DataOperate::verifyUUID(QString strUUID, int index, QString name)
{
    if(strUUID.contains("_"))
    {
        QStringList strList = strUUID.split("_");
        if(strList.length() == 2)
        {
            if(index == QString(strList.at(0)).toInt() && name == strList.at(1))
            {
                return true;
            }
        }
    }
    return false;

}

void DataOperate::verifyData()
{

}


//void DataOperate::forTemplate(QList<ConfData> &listConf, FUNC)
void DataOperate::forTemplate(int a, FUNC)
{
    for(int i = 0; i < a; ++i)
    {
        //        FUNC(a);
    }
}

void DataOperate::mapDataToVector(int lineIndex, QList<QPointF> pointList,
                                  QVector<double> &x, QVector<double> &y)
{
    for(int ci = 0; ci < pointList.length(); ++ci)
    {
        int pointYValue = setYAxisValue(lineIndex, pointList.at(ci).y());
        x << pointList.at(ci).x();
        y << pointYValue;
    }
}



void DataOperate::mapDataToVector(QString uuid, int pointIndex, QVector<double> &x, QVector<double> &y
                                  ,double xValue, double yValue)
{
    //    getGlobalDataInfos();

    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString UUID = setUUID(confData.index, confData.name);
        if(UUID == uuid)
        {
            QList<QPointF> pointList = confData.point;
            for(int ci = 0; ci < pointList.length(); ++ci)
            {
                if(pointIndex == ci)
                {
                    x << xValue;
                    y << getPointYValueByConfYValue(confData.index, yValue);
                }
                else
                {
                    x << pointList.at(ci).x();
                    y << setYAxisValue(confData.index, pointList.at(ci).y());
                }
            }
            //            m_listConfData[i] = confData;
            //            getGlobalDataInfos();
            return;
        }
    }
}

// 添加线
void DataOperate::addLineData(int index, QString name, QVector<double> x, QVector<double> y)
{
    ConfData confData;
    confData.index = index;
    confData.name = name;
    confData.point = vectorToPointFValue(x, y);
    m_listConfData.append(confData);
}

// 添加点
void DataOperate::addPointData(QString UUID, double x, double y)
{
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);

        if(nowUUID == UUID)
        {
            confData.point.append(QPointF(x, y));
            m_listConfData[i] = confData;
            return;
        }
    }
    qDebug() << "line__" << __LINE__ << "addPoint write data error";
}

void DataOperate::modifyPointData(QString UUID, int pointIndex, double x, double y)
{

    //    qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :yyyyyyyyyyyyyyyyyyyyyyyy" <<  y;
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);
        if(nowUUID == UUID)
        {
            for(int ci = 0; ci < confData.point.length(); ++ci)
            {
                if(ci == pointIndex)
                {
                    int yValue = getConfYValueByPointYValue(confData.index, y);
                    //                    qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :yValueyValueyValueyValueyValueyValueyValueyValueyValueyValue" <<  yValue;
                    //                    qDebug() <<"modify:" <<QPointF(roundAxisValue(x), yValue);
                    confData.point[ci] = QPointF(roundAxisValue(x), roundAxisValue(yValue));
                    m_listConfData[i] = confData;
                    //                                        qDebug() << "+++++++++++++++++++++++";
                    //                                        getGlobalDataInfos();
                    //                                        qDebug() << "+++++++++++++++++++++++";
                    return;
                }
            }
        }
    }
}

void DataOperate::delLineData(QString UUID)
{
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);
        if(nowUUID == UUID)
        {
            m_listConfData.removeAt(i);
            return;
        }
    }
    qDebug() << "line__" << __LINE__ << "delLine write data error";
}

void DataOperate::delPointData(QString UUID, int pointIndex)
{
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);
        if(nowUUID == UUID)
        {
            for(int ci = 0; ci < confData.point.length(); ++ci)
            {
                if(ci == pointIndex)
                {
                    confData.point.removeAt(ci);
                    m_listConfData[i] = confData;
                    return;
                }
            }
        }
    }
    qDebug() << "line__" << __LINE__ << "delPoint write data error";
}

int DataOperate::roundAxisValue(double x)
{
    // 将X轴坐标转化为
    return qRound(x);
}

int DataOperate::getMaxXAxisValue(QList<QPointF> pointFList)
{
    int maxId = 0;
    QList<int > idList;
    for(int i = 0; i < pointFList.length(); i++)
    {
        // 将X轴坐标转化为
        idList.append(roundAxisValue(pointFList.at(i).x()));
    }
    qSort(idList.begin(), idList.end());
    maxId = idList[idList.length() - 1] + 1;
    return maxId;

}


int DataOperate::setYAxisValue(int lineIndex, int yValue)
{
    int maxRangeY = getYAxisMaxValue();
    lineIndex++;
    //    qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :" <<  maxRangeY << lineIndex;
    return yValue == 0 ?
                maxRangeY - (2*lineIndex) + 1:
                maxRangeY - (2*lineIndex) + 2;
}

int DataOperate::getYAxisMaxValue()
{
    int yMaxValue = getAddNewLineIndex();

    if(yMaxValue * 2 > m_maxRangeY)
    {
        return  yMaxValue * 2;
    }
    return m_maxRangeY;
}

int DataOperate::getAddNewLineIndex()
{
    int maxId = 0;

    if(m_listConfData.length() > 0)
    {
        if(m_isUpFlag)
        {
            maxId =  (m_listConfData.length() + 1);
        }
        else
        {
            QList<int > idList;
            for(int i = 0; i < m_listConfData.length(); i++)
            {
                idList.append(m_listConfData.at(i).index);
            }
            qSort(idList.begin(), idList.end());
            maxId = idList[idList.length() - 1] + 1;
        }

    }

    return maxId;
}

int DataOperate::getConfDataMaxIndex()
{
    QList<int > idList;
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        idList.append(m_listConfData.at(i).index);
    }
    qSort(idList.begin(), idList.end());

    if(m_isUpFlag)
    {
        return m_listConfData.length();
    }
    else
    {
        return idList[idList.length() - 1];
    }
}

QString DataOperate::getAddNewLineName(int index)
{
    return QString("%1%2").arg("line").arg(index);
}

QList<QPointF> DataOperate::vectorToPointFValue(QVector<double> x, QVector<double> y)
{
    QList<QPointF> listPoint;
    for(int i = 0; i < x.length(); i++)
    {
        listPoint.append(QPointF(x.at(i), y.at(i)));
    }
    return listPoint;
}

void DataOperate::pointToVectorValue(QList<QPointF> listPointf, QVector<double> &x, QVector<double> &y)
{
    for(int ci = 0; ci < listPointf.length(); ++ci)
    {
        x << listPointf.at(ci).x();
        y << listPointf.at(ci).y();
    }
}

void DataOperate::clearAllData()
{
    m_listConfData.clear();
    m_isUpFlag = false;
    m_maxRangeY = 10;
}


QList<QPointF> DataOperate::getLineDataByIndex(QString UUID)
{
    QList<QPointF> pointList;
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);
        if(nowUUID == UUID)
        {
            pointList = m_listConfData.at(i).point;
        }
    }
    return pointList;
}

int DataOperate::getLineIndexByUUID(QString UUID)
{

    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        QString nowUUID = setUUID(confData.index, confData.name);
        if(nowUUID == UUID)
        {
            return confData.index;
        }
    }
    return -1;
}

void DataOperate::getPointInfoByPointValue(QString &UUID, int &pointIndex, QPointF pointF)
{

    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QList<QPointF> pointList = confData.point;

        for(int ci = 0; ci < pointList.length(); ci++)
        {
            QPointF cntPointF = pointList.at(ci);

            int yAxisValue = setYAxisValue(confData.index, cntPointF.y());
            //            bool mm = (qAbs(yAxisValue - pointF.y())) <= m_checkRange;
            //            bool yy = (qAbs(cntPointF.x() - pointF.x())) <= m_checkRange;
            //            qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :" <<  mm << yy << ci << confData.name << yAxisValue << pointF.y() << cntPointF.y();
            if((qAbs(yAxisValue - pointF.y())) <= m_checkRange &&
                    (qAbs(cntPointF.x() - pointF.x())) <= m_checkRange)
            {
                //                qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :dddddddddddddddddd" <<  ci;
                UUID = setUUID(confData.index, confData.name);
                pointIndex = ci;
                return;
            }
        }
    }
    UUID = "";
    pointIndex = -1;
    //    qDebug()<< "getPointInfoByPointValue error!";
}

qreal DataOperate::getPointYValueByConfYValue(int cntIndex, qreal y)
{
    cntIndex++;
    m_maxRangeY = getYAxisMaxValue();
    int maxYAxis = m_maxRangeY - (2*cntIndex) + 2;
    int minYAxis = m_maxRangeY - (2*cntIndex) + 1;

    qreal yAxisValue = 0;

    if(y < maxYAxis && y > minYAxis)
    {
        yAxisValue = y;
    }
    else if(y >= maxYAxis)
    {
        yAxisValue = maxYAxis;
    }
    else
    {
        yAxisValue = minYAxis;
    }
    return yAxisValue;
}

int DataOperate::getConfYValueByPointYValue(int cntIndex, qreal y)
{
    cntIndex++;
    int maxYAxis = m_maxRangeY - (2*cntIndex) + 2;
    int minYAxis = m_maxRangeY - (2*cntIndex) + 1;

    int yAxisValue = 0;

    if(y < maxYAxis && y > minYAxis)
    {
        y = qRound(y);
    }
    else
    {
        if(y >= maxYAxis)
        {
            yAxisValue = 1;
        }
        else
        {
            yAxisValue = 0;
        }
    }

    return yAxisValue;
}

int DataOperate::getConfDataLen()
{

    return m_listConfData.length();
}

bool DataOperate::chkCntLintPassMaxIndex(int lineIndex)
{
    // 获取当前线的最大Y值
    if((lineIndex+1) * 2 > m_maxRangeY)
    {
        return true;
    }
    return false;

}

void DataOperate::reRenderConfData()
{
    // 重新渲染数据： 把当前的点加入数据中，
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);
        //        int index = confData.index;
        qDebug() << "cntPointFddd" << confData.point;
        //        ConfData confData = m_listConfData.at(i);
        //        QString nowUUID = setUUID(confData.index, confData.name);

        //        if(nowUUID == UUID)
        //        {
        //            confData.point.append(QPointF(x, y));
        //            m_listConfData[i] = confData;
        //            return;
        //        }
    }
}

void DataOperate::renderConfData()
{
    // 直接 把当前的点加入数据中，
    for(int i = 0; i < m_listConfData.length(); ++i)
    {
        ConfData confData = m_listConfData.at(i);



    }
}

void DataOperate::getGlobalDataInfos()
{
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        //        int index = confData.index;
        qDebug() << "cntPointF" << confData.point;
    }
}

void DataOperate::setSaveFileName(QString fileName)
{
    m_saveFileName = fileName;
}

void DataOperate::saveChangedConfData()
{
    if(m_saveFileName == "")
    {
        m_saveFileName = INI_PATH;
    }
    PlotChartUtils::GetInstance().writeConfData(m_saveFileName, m_listConfData);
}

void DataOperate::saveAnOtherDataFile(QString fileName)
{
    clearFileInfos(fileName);

    PlotChartUtils::GetInstance().writeConfData(fileName, m_listConfData);
}

void DataOperate::moveUpLine(QList<ConfData> &listConfData, QString UUID)
{
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        if(strUUID == UUID)
        {
            if(i == 0)
            {
                qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] : Now is the most top!" ;
                return;
            }
            else
            {
                qSwap(m_listConfData[i].index, m_listConfData[i - 1].index);
                listConfData = m_listConfData;
                return;
            }
        }
    }

}

void DataOperate::moveDownLine(QList<ConfData> &listConfData, QString UUID)
{
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        if(strUUID == UUID)
        {
            if(i == m_listConfData.length() - 1)
            {
                qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] : Now is the most bottom!" ;
                return;
            }
            else
            {
                qSwap(m_listConfData[i].index, m_listConfData[i + 1].index);
                listConfData = m_listConfData;
                return;
            }
        }
    }

}


// 验证插入线的点是否在有效范围
bool DataOperate::chkCntYIsValidRange(double yValue, int &cntLineIndex)
{
    m_maxRangeY = getYAxisMaxValue();
    if(m_maxRangeY > yValue)
    {
        // 这个是在底部
        for(int cntIndex = 1; cntIndex <= m_maxRangeY/2 ; ++cntIndex)
        {
            int maxYAxis = m_maxRangeY - (2*cntIndex) + 2;
            int minYAxis = m_maxRangeY - (2*cntIndex) + 1;
            //            qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :" <<  maxYAxis << minYAxis << qRound(yValue);

            if(yValue <= maxYAxis && yValue >= minYAxis)
            {
                cntLineIndex = cntIndex - 1;
                return true;
            }
        }
    }
    else
    {
        // 这个是在顶部
    }
    return false;
}


// 判断此区域是否存在
bool DataOperate::chkNowRangeIsExist(int cntLineIndex)
{
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        if(cntLineIndex == confData.index)
        {
            return true;
        }
    }
    return false;
}

int DataOperate::isUpFlagValue(int lineIndex, int arrIndex)
{
    return m_isUpFlag ? arrIndex : lineIndex;
}

void DataOperate::modidyConfLegendByUUID(QString UUID, QString newName)
{
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        if(strUUID == UUID)
        {
            confData.name = newName;
            m_listConfData[i] = confData;
            return;
        }
    }
    qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] : modify newName is fail";
}

QList<QString> DataOperate::getCBoxFilesData()
{
    QList<QString> fileNames;
    if(dirNotMkDir(INI_DIR))
    {
        fileNames = PlotChartUtils::GetInstance().getLocalPathConfFileName(INI_DIR);
    }
    return fileNames;
}


// 判断文件是否存在，不存在创建
void DataOperate::existNotMkDir(QString fileName)
{
    QString absPath;
    if(!chkDirIsExis(fileName))
    {

        QFileInfo file(fileName);
        absPath = file.absolutePath();
        QDir dir;
        dir.mkpath(absPath);

    }

}

bool DataOperate::chkDirIsExis(QString dirPath)
{
    QFileInfo fileInfo(dirPath);
    if(fileInfo.isDir())
    {
        return true;
    }
    return false;
}

bool DataOperate::dirNotMkDir(QString dirPath)
{
    QDir *dir = new QDir;
    return dir->exists(dirPath) ?
                true :
                dir->mkdir(dirPath) ? true : false;

}

void DataOperate::clearFileInfos(QString fileName)
{
    QFile file(fileName);
    file.resize(0);
    file.close();
}

bool DataOperate::delFileInfos(QString fileName)
{
    QFile fileTemp(fileName);
    return fileTemp.remove();
}

// 检查文件是否存在
bool DataOperate::checkFileIsExist(QString fileName)
{
    QFile fileTemp(fileName);
    return fileTemp.exists();
}

int DataOperate::getLineMidValue(QString UUID)
{
    getNextLineDelayTime();

    int spaceValue = -1;
    QList<QPointF> cntLinePoint;
    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        if(strUUID == UUID)
        {
            cntLinePoint = confData.point;
            qSort(cntLinePoint.begin(), cntLinePoint.end(),
                  [=](const QPointF &pointA, const QPointF &pointB){
                return pointA.x() < pointB.x();
            });
        }
    }

    for(int cntIndex = 0; cntIndex < cntLinePoint.length(); cntIndex++)
    {
        for(int nextIndex = cntIndex + 1; nextIndex < cntLinePoint.length(); nextIndex++)
        {
            qreal yValue = cntLinePoint.at(cntIndex).y();
            qreal nextYValue = cntLinePoint.at(nextIndex).y();


            if(yValue == nextYValue && cntIndex > 0 && ((nextIndex + 1) < cntLinePoint.length()))
            {
                qreal yPreValue = cntLinePoint.at(cntIndex -1 ).y(); // 当前点后一个
                qreal yNextVaue = cntLinePoint.at(nextIndex + 1).y(); // 当前点前一个

                qreal xPreValue = cntLinePoint.at(cntIndex -1 ).x(); // 当前点后一个
                qreal xNextVaue = cntLinePoint.at(nextIndex + 1).x(); // 当前点前一个

                if(yNextVaue == yPreValue)
                {
                    spaceValue = xNextVaue - xPreValue;
                    return spaceValue;
                }
            }
        }
    }
    return spaceValue;
}


// 获取所有线中间的间隔值
QMap<QString, int> DataOperate::getAllLineMidValue()
{
    QMap<QString, int> mapAllMidValue;
    int spaceValue = -1;
    QList<QPointF> cntLinePoint;

    for(int i = 0; i < m_listConfData.length(); i++)
    {
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        cntLinePoint = confData.point;
        qSort(cntLinePoint.begin(), cntLinePoint.end(),
              [=](const QPointF &pointA, const QPointF &pointB){
            return pointA.x() < pointB.x();
        });

        for(int cntIndex = 0; cntIndex < cntLinePoint.length(); cntIndex++)
        {
            for(int nextIndex = cntIndex + 1; nextIndex < cntLinePoint.length(); nextIndex++)
            {
                //            qreal xValue = cntLinePoint.at(cntIndex).x();
                qreal yValue = cntLinePoint.at(cntIndex).y();
                //            qreal nextXValue = cntLinePoint.at(nextIndex).x();
                qreal nextYValue = cntLinePoint.at(nextIndex).y();

                if(yValue == nextYValue && cntIndex > 0 && ((nextIndex + 1) < cntLinePoint.length()))
                {
                    qreal yPreValue = cntLinePoint.at(cntIndex -1 ).y(); // 当前点后一个
                    qreal yNextVaue = cntLinePoint.at(nextIndex + 1).y(); // 当前点前一个
                    qreal xPreValue = cntLinePoint.at(cntIndex -1 ).x(); // 当前点后一个
                    qreal xNextVaue = cntLinePoint.at(nextIndex + 1).x(); // 当前点前一个

                    if(yNextVaue == yPreValue)
                    {
                        spaceValue = xNextVaue - xPreValue;
                        mapAllMidValue.insert(strUUID, spaceValue);
                    }
                }
            }
        }
    }

    return mapAllMidValue;
}


// 获取下一条线的延迟时间
void DataOperate::getNextLineDelayTime()
{
    QMap<QString, int> mapAllDelayTime;


    for(int i = 0; i < m_listConfData.length(); i++)
    {
        int delayTime = 0;
        ConfData confData = m_listConfData.at(i);
        QString strUUID = setUUID(confData.index, confData.name);

        if((i + 1) < m_listConfData.length())
        {
            QList<QPointF> cntLinePoint = confData.point;
            QList<QPointF> nextLinePoint = m_listConfData.at(i+1).point;

            delayTime = nextLinePoint.at(1).x() - cntLinePoint.at(1).x();
            mapAllDelayTime.insert(strUUID, delayTime);
        }
        else if((i + 1) == m_listConfData.length())
        {
            mapAllDelayTime.insert(strUUID, delayTime);
        }
    }

    QMapIterator<QString, int> mapItor(mapAllDelayTime);
    while (mapItor.hasNext()) {
        mapItor.next();
        qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :" <<  mapItor.key() << mapItor.value();
    }


    for(int mi = 0; mi < mapAllDelayTime.count(); ++mi)
    {
        qDebug() << "[" << __FUNCTION__ <<__LINE__ << "] :" <<  mapAllDelayTime[mi];
    }

//    QMap<QString, int>::iterator DTItor;
//    for(DTItor = )
//    {

//    }
}

int *DataOperate::readTData()
{
    int t[20];

    // 结构：
    /**
    ** 1. 第一条线的延迟时间
    ** 2. 第一条线的保持时间
    ** 3. 第二条线的延迟时间
    ** 4. 第二条线的保持时间
    ** 5. 第三条线的延迟时间
    ** 6. 第四条线的保持时间
    **/


}






